From e3832662ea7d593720f100d222e85e4c20a00547 Mon Sep 17 00:00:00 2001 From: =?utf8?q?=C3=98yvind=20Kol=C3=A5s?= Date: Wed, 29 Aug 2018 15:28:41 +0200 Subject: [PATCH] babl-fish-reference: implement floating point version of reference path This relies on conversions, linear or planar, being registered to and from RGBA float, similar to the already existing reference conversions in double. To enable use of it set the environment variable BABL_REFERENCE_FLOAT to any value, babl will crash if the above requirement is not met for a requested conversion - permitting adding it - fallback code could be added that implements it using the double versions when missing - but not having a full coverage at least for the commonly used formats defeats the purpose. --- babl/babl-fish-reference.c | 297 +++++++++++++++++++++---------------- 1 file changed, 170 insertions(+), 127 deletions(-) diff --git a/babl/babl-fish-reference.c b/babl/babl-fish-reference.c index 3eff1ca..7ae5455 100644 --- a/babl/babl-fish-reference.c +++ b/babl/babl-fish-reference.c @@ -97,6 +97,9 @@ create_name (const Babl *source, #endif +/* need an internal version that only ever does double, + * for use in path evaluation? and perhaps even self evaluation of float code path? + */ Babl * babl_fish_reference (const Babl *source, const Babl *destination) @@ -606,7 +609,6 @@ process_same_model (const Babl *babl, char *destination, long n) { - void *double_buf; const void *type_float = babl_type_from_id (BABL_FLOAT); #define MAX(a, b) ((a) > (b) ? (a) : (b)) if (BABL (babl->fish.source) == BABL (babl->fish.destination)) @@ -619,67 +621,68 @@ process_same_model (const Babl *babl, } - double_buf = babl_malloc (sizeof (double) * n * + + + if ((babl->fish.source->format.type[0]->bits < 32 || + babl->fish.source->format.type[0] == type_float) && + (babl->fish.destination->format.type[0]->bits < 32 || + babl->fish.destination->format.type[0] == type_float)) + { + void *float_buf = babl_malloc (sizeof (float) * n * MAX (BABL (babl->fish.source)->format.model->components, BABL (babl->fish.source)->format.components)); -#undef MAX - - if (compatible_components ((void*)babl->fish.source, - (void*)babl->fish.destination)) + if (compatible_components ((void*)babl->fish.source, + (void*)babl->fish.destination)) { - - if ((babl->fish.source->format.type[0]->bits < 32 || - babl->fish.source->format.type[0] == type_float) && - (babl->fish.destination->format.type[0]->bits < 32 || - babl->fish.destination->format.type[0] == type_float)) - { ncomponent_convert_to_float ( (BablFormat *) BABL (babl->fish.source), (char *) source, - double_buf, + float_buf, n); ncomponent_convert_from_float ( (BablFormat *) BABL (babl->fish.destination), - double_buf, + float_buf, (char *) destination, n); - } - else - { - ncomponent_convert_to_double ( + } + else + { + convert_to_float ( (BablFormat *) BABL (babl->fish.source), (char *) source, - double_buf, + float_buf, n); - ncomponent_convert_from_double ( + + convert_from_float ( (BablFormat *) BABL (babl->fish.destination), - double_buf, + float_buf, (char *) destination, n); - } } + babl_free (float_buf); + } else + { + void *double_buf = babl_malloc (sizeof (double) * n * + MAX (BABL (babl->fish.source)->format.model->components, + BABL (babl->fish.source)->format.components)); +#undef MAX + if (compatible_components ((void*)babl->fish.source, + (void*)babl->fish.destination)) { - - if ((babl->fish.source->format.type[0]->bits < 32 || - babl->fish.source->format.type[0] == type_float) && - (babl->fish.destination->format.type[0]->bits < 32 || - babl->fish.destination->format.type[0] == type_float)) - { - convert_to_float ( + ncomponent_convert_to_double ( (BablFormat *) BABL (babl->fish.source), (char *) source, double_buf, n); - - convert_from_float ( + ncomponent_convert_from_double ( (BablFormat *) BABL (babl->fish.destination), double_buf, (char *) destination, n); - } - else - { + } + else + { convert_to_double ( (BablFormat *) BABL (babl->fish.source), (char *) source, @@ -691,9 +694,9 @@ process_same_model (const Babl *babl, double_buf, (char *) destination, n); - } } - babl_free (double_buf); + babl_free (double_buf); + } } void @@ -709,6 +712,10 @@ babl_fish_reference_process (const Babl *babl, Babl *rgba_image = NULL; Babl *destination_image = NULL; + static int allow_float_reference = -1; + if (allow_float_reference == -1) + allow_float_reference = getenv ("BABL_REFERENCE_FLOAT") ? 1 : 0; + if ((BABL (babl->fish.source)->format.model == BABL (babl->fish.destination)->format.model) && (BABL (babl->fish.source)->format.space == @@ -725,57 +732,75 @@ babl_fish_reference_process (const Babl *babl, return; } - if (0 && (babl->fish.source->format.type[0]->bits < 32 || + if (allow_float_reference && + (babl->fish.source->format.type[0]->bits < 32 || babl->fish.source->format.type[0] == type_float) && (babl->fish.destination->format.type[0]->bits < 32 || babl->fish.destination->format.type[0] == type_float)) { -/* this code path is wip - not quite working yet, and needs resyncing - with double code that has gotten unneeded buffer allocation/copying - improvements */ - void *source_float_buf; - void *rgba_float_buf; - void *destination_float_buf; - - source_float_buf = babl_malloc (sizeof (float) * n * - BABL (babl->fish.source)->format.model->components); - rgba_float_buf = babl_malloc (sizeof (float) * n * 4); - destination_float_buf = babl_malloc (sizeof (float) * n * - BABL (babl->fish.destination)->format.model->components); - - source_image = babl_image_from_linear ( - source_float_buf, BABL (BABL ((babl->fish.source))->format.model)); - rgba_image = babl_image_from_linear ( - rgba_float_buf, babl_format_with_space ("RGBA float", - BABL (BABL ((babl->fish.source))->format.space))); - destination_image = babl_image_from_linear ( - destination_float_buf, babl_format_with_space ("RGBA float", - BABL (BABL ((babl->fish.destination))->format.space))); - - convert_to_float ( - (BablFormat *) BABL (babl->fish.source), - source, - source_float_buf, - n - ); + void *source_float_buf_alloc = NULL; + void *source_float_buf; + void *rgba_float_buf_alloc = NULL; + void *rgba_float_buf; + void *destination_float_buf_alloc = NULL; + void *destination_float_buf; + + if (babl->fish.source->format.type[0] == type_float && + BABL(babl->fish.source)->format.components == + BABL(babl->fish.source)->format.model->components && 0) + { + source_float_buf = (void*)source; + source_image = babl_image_from_linear ( + source_float_buf, + babl_format_with_model_as_type ((void*)((babl->fish.source))->format.model, + type_float)); + } + else + { + source_float_buf_alloc = babl_malloc (sizeof (float) * n * + BABL (babl->fish.source)->format.model->components); - { - char src_name[256]; - Babl *conv; - if (babl->fish.source->class_type == BABL_FORMAT) - sprintf (src_name, "%s float", - babl_get_name (BABL (babl->fish.source->format.model))); - else if (babl->fish.source->class_type == BABL_MODEL) - sprintf (src_name, "%s float", - babl_get_name (BABL (babl->fish.source))); - - conv = - assert_conversion_find ( - babl_format_with_space (src_name, - BABL (babl->fish.source)), - babl_format_with_space ("RGBA float", - BABL (BABL ((babl->fish.source))->format.space)) + source_float_buf = source_float_buf_alloc; + source_image = babl_image_from_linear ( + source_float_buf, + babl_format_with_model_as_type (BABL(BABL ((babl->fish.source))->format.model), + type_float)); + convert_to_float ( + (BablFormat *) BABL (babl->fish.source), + source, + source_float_buf, + n ); + } + + if (babl_model_is ((void*)babl->fish.source->format.model, "RGBA")) + { + rgba_float_buf = source_float_buf; + rgba_image = babl_image_from_linear ( + rgba_float_buf, + (void*)babl->fish.source->format.model); + } + else + { + char src_name[256]; + Babl *conv; + + sprintf (src_name, "%s float", babl_get_name((void*)babl->fish.source->format.model)); + conv = + assert_conversion_find ( + babl_format_with_space (src_name, + BABL (BABL ((babl->fish.source))->format.space)), + babl_format_with_space ("RGBA float", + BABL (BABL ((babl->fish.source))->format.space))); + + rgba_float_buf_alloc = babl_malloc (sizeof (float) * n * 4); + rgba_float_buf = rgba_float_buf_alloc; + + rgba_image = babl_image_from_linear ( + rgba_float_buf, + babl_format_with_space ("RGBA float", + BABL (BABL ((babl->fish.source))->format.space))); + if (conv->class_type == BABL_CONVERSION_PLANAR) { @@ -791,40 +816,56 @@ babl_fish_reference_process (const Babl *babl, source_float_buf, rgba_float_buf, n); } - else babl_fatal ("oops"); - } - if (((babl->fish.source)->format.space != - ((babl->fish.destination)->format.space))) - { - float matrix[9]; - float *rgba = rgba_float_buf; - babl_matrix_mul_matrixf ( - (babl->fish.destination)->format.space->space.XYZtoRGBf, - (babl->fish.source)->format.space->space.RGBtoXYZf, - matrix); - - babl_matrix_mul_vectorff_buf4 (matrix, rgba, rgba, n); - } - { - char dst_name[256]; - Babl *conv; - if (babl->fish.destination->class_type == BABL_FORMAT) - sprintf (dst_name, "%s float", - babl_get_name (BABL (babl->fish.destination->format.model))); - else if (babl->fish.destination->class_type == BABL_MODEL) - sprintf (dst_name, "%s float", - babl_get_name (BABL (babl->fish.destination))); - conv = - assert_conversion_find ( - babl_format_with_space ("RGBA float", - BABL (BABL ((babl->fish.destination))->format.space)), - babl_format_with_space (dst_name, - BABL (babl->fish.destination))); + } - if (conv->class_type == BABL_CONVERSION_PLANAR) + if (((babl->fish.source)->format.space != + ((babl->fish.destination)->format.space))) + { + float matrix[9]; + float *rgba = rgba_float_buf; + babl_matrix_mul_matrixf ( + (babl->fish.destination)->format.space->space.XYZtoRGBf, + (babl->fish.source)->format.space->space.RGBtoXYZf, + matrix); + + babl_matrix_mul_vectorff_buf4 (matrix, rgba, rgba, n); + } + + { + char dst_name[256]; + Babl *conv; + const Babl *destination_float_format; + sprintf (dst_name, "%s float", babl_get_name((void*)babl->fish.destination->format.model)); + destination_float_format = + babl_format_with_space (dst_name, + BABL (BABL ((babl->fish.destination))->format.space)); + + if( + babl_format_with_space ("RGBA float", + BABL (BABL ((babl->fish.destination))->format.space)) == + babl_format_with_space (dst_name, + BABL (BABL ((babl->fish.destination))->format.space))) + { + destination_float_buf = rgba_float_buf; + } + else { + destination_float_buf_alloc = babl_malloc (sizeof (float) * n * + BABL (babl->fish.destination)->format.model->components); + destination_float_buf = destination_float_buf_alloc; + conv = + assert_conversion_find ( + babl_format_with_space ("RGBA float", + BABL (BABL ((babl->fish.destination))->format.space)), + babl_format_with_space (dst_name, + BABL (BABL ((babl->fish.destination))->format.space))); + + if (conv->class_type == BABL_CONVERSION_PLANAR) + { + destination_image = babl_image_from_linear ( + destination_float_buf, destination_float_format); babl_conversion_process ( conv, (void*)rgba_image, (void*)destination_image, @@ -837,19 +878,23 @@ babl_fish_reference_process (const Babl *babl, rgba_float_buf, destination_float_buf, n); } - else babl_fatal ("oops"); - } - convert_from_float ( - (BablFormat *) BABL (babl->fish.destination), - destination_float_buf, - destination, - n - ); + } + } - babl_free (destination_float_buf); - babl_free (rgba_float_buf); - babl_free (source_float_buf); + convert_from_float ( + (BablFormat *) BABL (babl->fish.destination), + destination_float_buf, + destination, + n + ); + + if (destination_float_buf_alloc) + babl_free (destination_float_buf_alloc); + if (rgba_float_buf_alloc) + babl_free (rgba_float_buf_alloc); + if (source_float_buf_alloc) + babl_free (source_float_buf_alloc); } else /* double */ { @@ -859,12 +904,11 @@ babl_fish_reference_process (const Babl *babl, void *rgba_double_buf; void *destination_double_buf_alloc = NULL; void *destination_double_buf; - + if (babl->fish.source->format.type[0] == type_double && - BABL(babl->fish.source)->format.components == + BABL(babl->fish.source)->format.components == BABL(babl->fish.source)->format.model->components && 0) { - fprintf (stderr, "hita\n"); source_double_buf = (void*)source; source_image = babl_image_from_linear ( source_double_buf, BABL (BABL ((babl->fish.source))->format.model)); @@ -873,7 +917,7 @@ babl_fish_reference_process (const Babl *babl, { source_double_buf_alloc = babl_malloc (sizeof (double) * n * BABL (babl->fish.source)->format.model->components); - + source_double_buf = source_double_buf_alloc; source_image = babl_image_from_linear ( source_double_buf, BABL (BABL ((babl->fish.source))->format.model)); @@ -949,7 +993,6 @@ babl_fish_reference_process (const Babl *babl, } else { - /* XXX : do this with format instead of model - more generic */ Babl *conv = assert_conversion_find (destination_rgba_format, BABL (babl->fish.destination)->format.model); -- 2.30.2